/**
 * Promise 是异步编程的一种解决方案
 * Promise对象代表一个异步操作，有三种状态：pending（进行中）、fulfilled（已成功）和rejected（已失败）
 * 一旦状态改变，就不会再变。Promise对象的状态改变，只有两种可能：从pending变为fulfilled和从pending变为rejected。
 * promise缺点 1、无法取消Promise，一旦新建它就会立即执行，无法中途取消 2、如果不设置回调函数，Promise内部抛出的错误，不会反应到外部 3、当处于pending状态时，无法得知目前进展到哪一个阶段（刚刚开始还是即将完成）
*/

/**
 * 1、基本用法
 * Promise对象是一个构造函数，用来生成Promise实例。
 * Promise构造函数接受一个函数作为参数，该函数的两个参数分别是resolve和reject
 * resolve函数的作用是，将Promise对象的状态从 pending 变为 resolved，在异步操作成功时调用，并将异步操作的结果，作为参数传递出去；
 * reject函数的作用是，将Promise对象的状态从从 pending 变为 rejected，在异步操作失败时调用，并将异步操作报出的错误，作为参数传递出去。
 *  */ 
const promise = new Promise((resolve, reject) => {
  if (true) {
    resolve()
  } else {
    reject()
  }
})

// then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用，第二个回调函数是Promise对象的状态变为rejected时调用。
promise.then(
  (res) => {
    console.log(res)
  }, 
  err => {
    console.log(err)
  }
)

// resolve一个promise,会根据resolve的promise状态决定当前状态，等待esolve的promise状态确定是一个异步的过程 ‘拆箱’
// resolve的promise为resolved状态 则走resolved状态的回调函数

const p1 = new Promise((resolve) => {
  resolve(1)
})
const p2 = new Promise((resolve) => {
  resolve(p1)
})
p2.then(res => {
  console.log(res);  // 1
},err => {
  console.log(err);
})

// resolve的promise为rejected状态 则走rejected状态的回调函数
const p3 = new Promise((resolve,reject) => {
  reject(3)
})
const p4 = new Promise((resolve) => {
  resolve(p3)
})
p4.then(res => {
  console.log(res);  
}, err => {
  console.log(err); // 3
})

// reject一个promise
// 并不会去等待reject的promise状态变化，直接reject这个promise，走rejected的回调函数
const p5 = new Promise((resolve, reject) => {
  reject(p3)
})
p5.then(res => {
  console.log(res);
},err => {
  console.log(err); // Promise { <rejected> 3 }
})

// 调用resolve或reject并不会终结 Promise 的参数函数的执行。
new Promise((resolve, reject) => {
  resolve(1);
  // return resolve(1)  最好在resolve或reject前面加return
  console.log(2);
}).then(r => {
  console.log(r);
});
// 2 1
